﻿using System;
using System.Collections.Generic;

namespace ZOIL.DataModel
{
    public class EqualityComparer<T> : IEqualityComparer<T>
    {
        public readonly Func<T, T, bool> EqualsMethod;
        public readonly Func<T, int> GetHashCodeMethod;

        public EqualityComparer(Func<T, T, bool> equalsMethod, Func<T, int> getHashCodeMethod)
        {
            EqualsMethod = equalsMethod;
            GetHashCodeMethod = getHashCodeMethod;
        }

        #region Implementation of IEqualityComparer<in T>

        /// <summary>
        /// Determines whether the specified objects are equal.
        /// </summary>
        /// <returns>
        /// true if the specified objects are equal; otherwise, false.
        /// </returns>
        /// <param name="x">The first object of type <paramref name="T"/> to compare.</param><param name="y">The second object of type <paramref name="T"/> to compare.</param>
        public bool Equals(T x, T y)
        {
            return EqualsMethod(x, y);
        }

        /// <summary>
        /// Returns a hash code for the specified object.
        /// </summary>
        /// <returns>
        /// A hash code for the specified object.
        /// </returns>
        /// <param name="obj">The <see cref="T:System.Object"/> for which a hash code is to be returned.</param><exception cref="T:System.ArgumentNullException">The type of <paramref name="obj"/> is a reference type and <paramref name="obj"/> is null.</exception>
        public int GetHashCode(T obj)
        {
            return GetHashCodeMethod(obj);
        }

        #endregion
    }
    public static class EqualityComparer
    {
        public static EqualityComparer<TU> Create<TU>(Func<TU, TU, bool> equalsMethod, Func<TU, int> getHashCodeMethod)
        {
            return new EqualityComparer<TU>(equalsMethod, getHashCodeMethod);
        }
    }
}